home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / libs / 3dvect39 / function.asm < prev    next >
Encoding:
Assembly Source File  |  1994-10-30  |  37.6 KB  |  1,259 lines

  1. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2. ;
  3. ; Filename     : move.asm
  4. ; Included from: Main Assembley Module
  5. ; Description  : Automatic object movement routines/functions
  6. ;
  7. ; Written by: John McCarthy
  8. ;             1316 Redwood Lane
  9. ;             Pickering, Ontario.
  10. ;             Canada, Earth, Milky Way (for those out-of-towners)
  11. ;             L1X 1C5
  12. ;
  13. ; Internet/Usenet:  BRIAN.MCCARTHY@CANREM.COM
  14. ;         Fidonet:  Brian McCarthy 1:229/15
  15. ;   RIME/Relaynet: ->CRS
  16. ;
  17. ; Home phone, (905) 831-1944, don't call at 2 am eh!
  18. ;
  19. ; John Mccarthy would really love to work for a company programming Robots
  20. ; or doing some high intensive CPU work.  Hint. Hint.
  21. ;
  22. ; Send me your protected mode source code!
  23. ; Send me your Objects!
  24. ; But most of all, Send me a postcard!!!!
  25. ;
  26. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  27.  
  28.          .386p
  29.  
  30. code32   segment para public use32
  31.          assume cs:code32, ds:code32
  32.  
  33.          include pmode.ext                  ; protected mode externals by TRAN
  34.          include irq.ext                    ; irq timing externals
  35.          include 3d.ext
  36.          include macros.inc
  37.          include equ.inc
  38.  
  39.          public _updvectors                 ; update vector positions/angles
  40.          public _calc_angles                ; calculate angles between objects di,si
  41.          public _calc_middle                ; calculate angles of ebx,ecx,ebp into x,y
  42.          public _get_displacement           ; calculate difference between object si and di
  43.          public _put_object                 ; put object si at ebx,ecx,ebp
  44.          public _get_location               ; get location of object esi
  45.          public _set_angle                  ; set object si to angle bx,cx,bp
  46.          public _get_angle                  ; get object si's angle
  47.          public _set_shape                  ; set shape of object si to ax
  48.          public _set_object_on              ; set main object si to on
  49.          public _set_object_off
  50.          public _set_sub_object_on          ; set sub-object on or off
  51.          public _set_sub_object_off
  52.          public _use_full_rotations         ; set rotation style of object
  53.          public _use_no_rotations
  54.          public _set_to_hi_bitmap           ; set object to be a static bitmap
  55.          public _set_to_lo_bitmap
  56.          public _set_bitmap_scaling         ; set bitmap base scaling for this object
  57.          public _search_next_available_object ; find next available object for use
  58.          public _init_object                ; initialize/clear object for use
  59.          public _move_si                    ; move object si to ebx,ecx,ebp in di
  60.          public _twist_si                   ; rotate object si to ebx,ecx,ebp in di
  61.          public _twist_xonly                ; rotate object si's x angle until = ebx, di = time
  62.          public _twist_yonly                ; rotate object si's y angle until = ecx, di = time
  63.          public _twist_zonly                ; rotate object si's z angle until = ebp, di = time
  64.          public _where_si                   ; where will object si be in di frames?
  65.          public _point_it                   ; point object si at object di
  66.          public _point_dir                  ; point object si in direction it is moving instantly
  67.          public _point_dir_time             ; point object si in direction it is moving in di frames
  68.          public _point_to                   ; point object si at location ebx,ecx,ebp
  69.          public _set_speed                  ; calculate velocity based on angles
  70.          public _set_xyzadds                ; set object world velocity values for location
  71.          public _set_xyzvadds               ; set object world velocity values for angle
  72.          public _point_time                 ; point obj di to bx,cx,bp in di frames
  73.          public _time_to_point              ; pre-cal point obj di to bx,cx,bp in di frames
  74.          public _nullpalette                ; only a null cross reference palette
  75.          public _set_xref_palette           ; set cross reference pal for object si to ebx
  76.          public _fix_xangle                 ; test/correct camera x angle wrap-around
  77.          public _fix_xangleq                ; test/correct camera x angle wrap-around - when using joystick
  78.          public _subtract_camera            ; subtract camera location from x,y,z
  79.          public _relative_velocity          ; calc relative velocity of objects si and di
  80.          public _add_xyzadds                ; add velocity of object esi to ebx,ecx,ebp
  81.          public _get_xyzadds                ; get xyzadds of object esi
  82.  
  83.          align 4
  84.  
  85. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  86. ;
  87. ; _updvectors: Update vector locations/angles (also does camera)
  88. ;
  89. ; In:
  90. ;    null
  91. ; Out:
  92. ;    null
  93. ;
  94. ; Notes:
  95. ; Routine is now called by irq, so animation/game continues in background. Much
  96. ; better method than using _irq_traces_past
  97. ;
  98. ; IRQ maintains a universal speed from 486dx66 machine to 386sx25 machine.
  99. ;
  100. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  101.  
  102. _updvectors:
  103.          align 4
  104.  
  105.          xor ebx,ebx
  106.  
  107.          i=0
  108.          rept maxobjects+1    ; generate unrolled update loop
  109.          local nuploc, nodecx, nodecy, nodecz
  110.  
  111.          cmp _acountx+i*2,bx
  112.          je s nodecx
  113.          dec _acountx+i*2
  114.          mov ax,_vxadds+i*2 ; update angles
  115.          add _vxs+i*2,ax
  116. nodecx:
  117.          cmp _acounty+i*2,bx
  118.          je s nodecy
  119.          dec _acounty+i*2
  120.          mov ax,_vyadds+i*2
  121.          add _vys+i*2,ax
  122. nodecy:
  123.          cmp _acountz+i*2,bx
  124.          je s nodecz
  125.          dec _acountz+i*2
  126.          mov ax,_vzadds+i*2
  127.          add _vzs+i*2,ax
  128. nodecz:
  129.  
  130.          cmp _lcount+i*2,bx
  131.          je s nuploc
  132.          dec _lcount+i*2
  133.  
  134.          mov eax,_xadds+i*4 ; update position
  135.          add _xs+i*4,eax
  136.          mov eax,_yadds+i*4
  137.          add _ys+i*4,eax
  138.          mov eax,_zadds+i*4
  139.          add _zs+i*4,eax
  140. nuploc:
  141.          i=i+1
  142.          endm
  143.  
  144.          ret
  145.  
  146. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  147. ;_put_object: Set object location
  148. ;In:
  149. ;   EBX - x point
  150. ;   ECX - y point
  151. ;   EBP - z point
  152. ;    SI - object #
  153. ;Out=In
  154. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  155.          align 4
  156. _put_object:
  157.          movzx esi,si
  158.          mov _xs[esi*4],ebx
  159.          mov _ys[esi*4],ecx
  160.          mov _zs[esi*4],ebp
  161.          ret
  162.  
  163. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  164. ;_get_location: Get object location
  165. ;In:
  166. ;   ESI - object #
  167. ;Out:
  168. ;   EBX - x point
  169. ;   ECX - y point
  170. ;   EBP - z point
  171. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  172.          align 4
  173. _get_location:
  174.          movzx esi,si
  175.          mov ebx,_xs[esi*4]
  176.          mov ecx,_ys[esi*4]
  177.          mov ebp,_zs[esi*4]
  178.          ret
  179.  
  180. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  181. ;_set_angle: Set object angle
  182. ;In:
  183. ;    BX - x angle (0-65536)
  184. ;    CX - y angle
  185. ;    BP - z angle
  186. ;    SI - object #
  187. ;Out=In
  188. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  189.          align 4
  190. _set_angle:
  191.          movzx esi,si
  192.          mov _vxs[esi*2],bx
  193.          mov _vys[esi*2],cx
  194.          mov _vzs[esi*2],bp
  195.          ret
  196.  
  197. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  198. ;_get_angle: Get object angle
  199. ;In:
  200. ;    SI - object #
  201. ;Out:
  202. ;    BX - x angle (0-65536)
  203. ;    CX - y angle
  204. ;    BP - z angle
  205. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  206.          align 4
  207. _get_angle:
  208.          movzx esi,si
  209.          mov bx,_vxs[esi*2]
  210.          mov cx,_vys[esi*2]
  211.          mov bp,_vzs[esi*2]
  212.          ret
  213.  
  214. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  215. ; set_shape: Set object shape
  216. ; In:
  217. ;     AX - shape of object (this later is used as an indexer in the _objbase table)
  218. ;     SI - object #
  219. ; Out=In
  220. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  221.          align 4
  222. _set_shape:
  223.          movzx esi,si
  224.          mov _whatshape[esi*2],ax
  225.          ret
  226.  
  227. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  228. ; set_object_on: Turn object on
  229. ; In:
  230. ;     SI - object # to make visible
  231. ; Out=In
  232. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  233.          align 4
  234. _set_object_on:
  235.          movzx esi,si
  236.          or _onoff[esi],mainobject_on
  237.          ret
  238.  
  239. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  240. ; set_object_off: Turn object off
  241. ; In:
  242. ;     SI - object # to stop drawing
  243. ; Out=In
  244. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  245.          align 4
  246. _set_object_off:
  247.          movzx esi,si
  248.          and _onoff[esi],-1-mainobject_on
  249.          ret
  250.  
  251. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  252. ; set_sub_object_on: Make angles and location refer to a sub object (arm, leg)
  253. ; In:
  254. ;     SI - object # to de_sineate as a sub-object
  255. ; Out=In
  256. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  257.          align 4
  258. _set_sub_object_on:
  259.          movzx esi,si
  260.          or _onoff[esi],sub_object_on
  261.          ret
  262.  
  263. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  264. ; set_sub_object_off: Make angles/locations/velicities refer to a sub object (arm, leg)
  265. ; In:
  266. ;     SI - object # to un-de_sineate as a sub-object
  267. ; Out=In
  268. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  269.          align 4
  270. _set_sub_object_off:
  271.          movzx esi,si
  272.          and _onoff[esi],-1-sub_object_on
  273.          ret
  274.  
  275. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  276. ; use_full_rotations: Make object free to rotate along any axis
  277. ; In:
  278. ;     SI - object #
  279. ; Out=In
  280. ;
  281. ;Notes:
  282. ;         This also clears the bitmap options below
  283. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  284.          align 4
  285. _use_full_rotations:
  286.          movzx esi,si
  287.          mov _userotate[esi],full_rotations
  288.          ret
  289.  
  290. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  291. ; use_no_rotations: Make object rigid along rotation axis (faster)
  292. ; In:
  293. ;     SI - object #
  294. ; Out=In
  295. ;
  296. ; Notes:
  297. ;   This also clears the bitmap options below
  298. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  299.          align 4
  300. _use_no_rotations:
  301.          movzx esi,si
  302.          mov _userotate[esi],no_rotation
  303.          ret
  304.  
  305. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  306. ; set_to_hi_bitmap: Make object a hi-res bitmap (like an explosion or something)
  307. ; In:
  308. ;     SI - object #
  309. ; Out=In
  310. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  311.          align 4
  312. _set_to_hi_bitmap:
  313.          movzx esi,si
  314.          mov _userotate[esi],s_himap
  315.          ret
  316.  
  317. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  318. ; set_to_lo_bitmap: Make object a lo-res _bitmap (like an explosion or something)
  319. ; In:
  320. ;     SI - object #
  321. ; Out=In
  322. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  323.          align 4
  324. _set_to_lo_bitmap:
  325.          movzx esi,si
  326.          mov _userotate[esi],s_lomap
  327.          ret
  328.  
  329. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  330. ; set_bitmap_scaling: Set scaling factors for bitmaps (explosions)
  331. ; In:
  332. ;     SI - object #
  333. ;     BX - x scaling factor for bitmap
  334. ;     CX - y scaling factor for bitmap
  335. ; Out=In
  336. ;
  337. ;Notes: This determines the bitmaps "Size" in the virtual world.
  338. ;       You do not have to make this smaller as the bitmap gets farther away,
  339. ;       as this is done automatically.
  340. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  341.          align 4
  342. _set_bitmap_scaling:
  343.          movzx esi,si
  344.          mov _bitobjx[esi*2],bx             ; bitmap scaling (gets added to _bitx and _bity)
  345.          mov _bitobjy[esi*2],cx
  346.          ret
  347.  
  348. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  349. ; search_next_available_object: Find an object which is not in use
  350. ; In:
  351. ;   null
  352. ; Out:
  353. ;  CF = 1 - no free objects
  354. ;   ESI - ?
  355. ;  CF = 0 - free object found
  356. ;   ESI - # of free object to be defined as you please
  357. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  358.          align 4
  359. _search_next_available_object:
  360.          xor esi,esi
  361. search_loop:
  362.          inc esi
  363.          cmp esi,maxobjects
  364.          je abort_srch
  365.          test _onoff[esi],mainobject_on+sub_object_on+hold_object
  366.          jnz short search_loop
  367.  
  368.          clc
  369.          ret
  370.  
  371. abort_srch:
  372.          stc                                ; carry set if no new object available (all are already used)
  373.          ret
  374.  
  375. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  376. ; init_object: reset all parameters of an object.
  377. ; In:
  378. ;    SI - # of object to reset
  379. ; Out:
  380. ;   null
  381. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  382.          align 4
  383. _init_object:
  384.          movzx esi,si
  385.          xor eax,eax
  386.          mov _userotate[esi],al
  387.          mov _onoff[esi],al
  388.          mov _xs[esi*4],eax
  389.          mov _ys[esi*4],eax
  390.          mov _zs[esi*4],eax
  391.          mov _xadds[esi*4],eax
  392.          mov _yadds[esi*4],eax
  393.          mov _zadds[esi*4],eax
  394.          mov _vxs[esi*2],ax
  395.          mov _vys[esi*2],ax
  396.          mov _vzs[esi*2],ax
  397.          mov _vxadds[esi*2],ax
  398.          mov _vyadds[esi*2],ax
  399.          mov _vzadds[esi*2],ax
  400.          mov _lcount[esi*2],ax
  401.          mov _acountx[esi*2],ax
  402.          mov _acounty[esi*2],ax
  403.          mov _acountz[esi*2],ax
  404.          mov _palxref[esi],al
  405.          mov _whatshape[esi*2],ax
  406.          ret
  407.  
  408. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  409. ; _move_si: Calculate velocity for moving object SI from wherever it is
  410. ;           now to EBX,ECX,EBP in DI frames
  411. ; In:
  412. ;    EBX - x location
  413. ;    ECX - y location
  414. ;    EBP - z location
  415. ;     SI - # of object to move
  416. ;     DI - # of frames to get there
  417. ; Out:
  418. ;    EBX - x velocity
  419. ;    ECX - y velocity
  420. ;    EBP - z velocity
  421. ;     SI - # of object to move
  422. ;     DI - # of frames to get there
  423. ;
  424. ; Notes:
  425. ;  move is 32 bit, make sure high words of registers are set!
  426. ;  time to get there is 16 bit. (if you need more, think! 65535 frames at
  427. ;  70 frames a sec is 15 minutes!)
  428. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  429.  
  430.          align 4
  431.  
  432. _move_si:
  433.          movzx esi,si
  434.  
  435.          sub ebx,_xs[esi*4]
  436.          sub ecx,_ys[esi*4]
  437.          sub ebp,_zs[esi*4]
  438.  
  439.          movzx edi,di
  440.  
  441.          mov eax,ebx                        ; 32 bit moves
  442.          cdq
  443.          idiv edi
  444.          mov ebx,eax
  445.  
  446.          mov eax,ecx
  447.          cdq
  448.          idiv edi
  449.          mov ecx,eax
  450.  
  451.          mov eax,ebp
  452.          cdq
  453.          idiv edi
  454.          mov ebp,eax
  455.  
  456.          ret
  457.  
  458.          align 4
  459.  
  460. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  461. ; _twist_si: calculate rotation velocities for object si from wherever
  462. ;            it is now to ebx,ecx,ebp in di frames
  463. ; In:
  464. ;    EBX - x angle
  465. ;    ECX - y angle
  466. ;    EBP - z angle
  467. ;     SI - # of object to spin/twist/roll...
  468. ;     DI - # of frames to get there
  469. ; Out:
  470. ;     BX - x anglular velocity
  471. ;     CX - y anglular velocity
  472. ;     BP - z anglular velocity
  473. ;     SI - # of object to spin/twist/roll...
  474. ;     DI - # of frames to get there
  475. ;
  476. ; Notes:
  477. ;   Rotate is  32 bit, make   sure   high  words  of  registers  are  set!
  478. ;   Time to get there is 16 bit.  Note: Although resulting angle  will  be
  479. ;   16 bit, input angle is 32 bit!.  This allows you to rotate many  times
  480. ;   before coming to rest at a specified angle  and  also  allows  you  to
  481. ;   specify the direction of rotation.    di  specifies  time  to  arrive.
  482. ;   Final location is absolute, not relative to current angle.
  483. ;
  484. ; eg 00000100 is "rotate forwards until 100 degrees"
  485. ;    00078000 is "rotate 7 full rotations and come to rest at 32768 degrees"
  486. ;    fffd9000 is "rotate backwards 2 rotations and come to rest at 9000h degrees"
  487. ;    fffffff0 is "rotate backwards until 65520 degrees (-16)"
  488. ;
  489. ; Therefore, to reverse the direction of rotation (but maintain  the  final
  490. ; position) xor ebx,0ffff0000h  (or ecx or ebp).  bx is final position, but
  491. ; top word of ebx determines direction and number of turns to get there.
  492. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  493.  
  494. _twist_si:
  495.          movzx esi,si
  496.  
  497.          sub bx,_vxs[esi*2]
  498.          sub cx,_vys[esi*2]
  499.          sub bp,_vzs[esi*2]
  500.  
  501.          movzx edi,di
  502.  
  503.          mov eax,ebx                        ; 32 bit rotate
  504.          cdq
  505.          idiv edi
  506.          mov ebx,eax
  507.  
  508.          mov eax,ecx
  509.          cdq
  510.          idiv edi
  511.          mov ecx,eax
  512.  
  513.          mov eax,ebp
  514.          cdq
  515.          idiv edi
  516.          mov ebp,eax
  517.  
  518.          ret
  519.  
  520. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  521. ; _twist_xonly:_rotate_point object si along single axis
  522. ; In:
  523. ;    EBX - x angle
  524. ;     SI - # of object to spin/twist/roll...
  525. ;     DI - # of frames to get there
  526. ; Out:
  527. ;     BX - x anglular velocity
  528. ;     SI - # of object to spin/twist/roll...
  529. ;     DI - # of frames to get there
  530. ;
  531. ; Notes:
  532. ;   Same as above...
  533. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  534.          align 4
  535. _twist_xonly:
  536.          movzx esi,si
  537.  
  538.          sub bx,_vxs[esi*2]
  539.  
  540.          movzx edi,di
  541.  
  542.          mov eax,ebx                        ; 32 bit rotate
  543.          cdq
  544.          idiv edi
  545.          mov ebx,eax
  546.  
  547.          ret
  548.  
  549. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  550. ; _twist_yonly:_rotate_point object si along single axis
  551. ; In:
  552. ;    ECX - y angle
  553. ;     SI - # of object to spin/twist/roll...
  554. ;     DI - # of frames to get there
  555. ; Out:
  556. ;     CX - x anglular velocity
  557. ;     SI - # of object to spin/twist/roll...
  558. ;     DI - # of frames to get there
  559. ;
  560. ; Notes:
  561. ;   Same as above...
  562. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  563.          align 4
  564. _twist_yonly:
  565.          movzx esi,si
  566.  
  567.          sub cx,_vys[esi*2]
  568.  
  569.          movzx edi,di
  570.  
  571.          mov eax,ecx                        ; 32 bit rotate
  572.          cdq
  573.          idiv edi
  574.          mov ecx,eax
  575.  
  576.          ret
  577.  
  578. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  579. ; _twist_zonly:_rotate_point object si along single axis
  580. ; In:
  581. ;    EBP - z angle
  582. ;     SI - # of object to spin/twist/roll...
  583. ;     DI - # of frames to get there
  584. ; Out:
  585. ;     BP - x anglular velocity
  586. ;     SI - # of object to spin/twist/roll...
  587. ;     DI - # of frames to get there
  588. ;
  589. ; Notes:
  590. ;   Same as above...
  591. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  592.          align 4
  593. _twist_zonly:
  594.          movzx esi,si
  595.  
  596.          sub bp,_vzs[esi*2]
  597.  
  598.          movzx edi,di
  599.  
  600.          mov eax,ebp                        ; 32 bit _rotate_point
  601.          cdq
  602.          idiv edi
  603.          mov ebp,eax
  604.  
  605.          ret
  606.  
  607. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  608. ; _calc_angles: Calculate angles between objects esi and edi.
  609. ; In:
  610. ;    SI - # of object to look at
  611. ;    DI - # of object to look from
  612. ; Out:
  613. ;    AX - x angle
  614. ;    BX - y angle
  615. ;
  616. ; Notes:
  617. ;   Angles are from point of view of DI.
  618. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  619.  
  620.          align 4
  621.  
  622. temp1    dd 0
  623. temp2    dd 0
  624.  
  625. _calc_angles:
  626.          call _get_displacement
  627.          mov di,_vzs[edi*2]
  628.  
  629. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  630. ; _calc_middle: Calculate angles to static point
  631. ; In:
  632. ;    EBX - x location
  633. ;    ECX - y location
  634. ;    EBP - z location
  635. ; Out:
  636. ;    AX - x angle
  637. ;    BX - y angle
  638. ;
  639. ; Notes:
  640. ;   Booga Boo
  641. ;
  642. ;   Y = arctan (x/z)
  643. ;   X = arctan ((x*sin(Y) + Z cos(Y)))/y)
  644. ;
  645. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  646.  
  647. _calc_middle:
  648.          push ecx ebx ebp
  649.  
  650.          mov ecx,ebx                        ; first get z,x plane, (y angle)
  651.          mov eax,ebp
  652.  
  653.          call _arctan
  654.  
  655.          mov temp2,eax                      ; save y angle
  656.          call _cosine                       ; set up 32bit sin/cos multipliers
  657.          mov temp1,eax
  658.          mov eax,temp2
  659.          call _sine
  660.  
  661.          pop ebp ebx                        ; now compute sqr(z^2+x^2) through y rotation
  662.  
  663.          imul ebx                           ; use angle from calculation above
  664.          shrd eax,edx,14
  665.          mov edi,eax
  666.          mov eax,temp1
  667.          imul ebp
  668.          shrd eax,edx,14
  669.          add eax,edi                        ; di = new z = run
  670.  
  671.          pop ecx
  672.  
  673.          call _arctan                       ; get ax=arctan(y/sqr(z^2+x^2))
  674.  
  675.          mov ebx,temp2                      ; bx = y angle , ax = x angle
  676.          ret
  677.  
  678.          align 4
  679.  
  680. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  681. ; _get_displacement: figure out displacement between two objects
  682. ; In:
  683. ;     SI - # of object to look at
  684. ;     DI - # of object to look from
  685. ; Out:
  686. ;    EBX - x distance (signed)
  687. ;    ECX - y distance
  688. ;    EBP - z distance
  689. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  690.  
  691. _get_displacement:
  692.          and edi,0000ffffh                  ; faster than movzx (but dont quote me on it)
  693.          and esi,0000ffffh
  694.  
  695.          mov ebx,_xs[esi*4]                 ; get displacement of esi to edi
  696.          sub ebx,_xs[edi*4]
  697.          mov ecx,_ys[esi*4]
  698.          sub ecx,_ys[edi*4]
  699.          mov ebp,_zs[esi*4]
  700.          sub ebp,_zs[edi*4]
  701.          ret
  702.  
  703.          align 4
  704.  
  705. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  706. ; _where_si: Figure out approximatly where object SI will be in DI frames.
  707. ; In:
  708. ;     SI - # of object to follow
  709. ;     DI - time
  710. ; Out:
  711. ;    EBX - x location
  712. ;    ECX - y location
  713. ;    EBP - z location
  714. ;     SI - zSI
  715. ;
  716. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  717.  
  718. _where_si:
  719.          and esi,0000ffffh
  720.  
  721.          mov ax,_lcount[esi*2]
  722.          or ax,ax
  723.          jne s nx
  724.  
  725.          mov ebx,_xs[esi*4]                 ; if object has no velocity, xs is position
  726.          mov ecx,_ys[esi*4]
  727.          mov ebp,_zs[esi*4]
  728.          ret
  729. nx:
  730.          cmp ax,di                          ; if di>_lcount, shorten to _lcount
  731.          ja s nxq
  732.          mov di,ax
  733. nxq:
  734.          and edi,0000ffffh
  735.  
  736.          mov eax,_xadds[esi*4]              ; figure out where object will be di*frames
  737.          imul edi
  738.          add eax,_xs[esi*4]
  739.          mov ebx,eax
  740.  
  741.          mov eax,_yadds[esi*4]
  742.          imul edi
  743.          add eax,_ys[esi*4]
  744.          mov ecx,eax
  745.  
  746.          mov eax,_zadds[esi*4]
  747.          imul edi
  748.          add eax,_zs[esi*4]
  749.          mov ebp,eax
  750.  
  751.          ret
  752.  
  753.          align 4
  754.  
  755. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  756. ; _point_it: Point object SI at object DI
  757. ; In:
  758. ;    SI = object # to point
  759. ;    DI = target object
  760. ; Out:
  761. ;   _vxs[esi*2]=AX= x angle (in case you need it)
  762. ;   _vys[esi*2]=BX= y angle
  763. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  764.  
  765. _point_it:
  766.          push esi edi
  767.          xchg si,di                         ; xchange so user doesn't get confused
  768.          push edi
  769.          call _calc_angles
  770.          pop edi
  771.          movzx edi,di
  772.          mov _vxs[edi*2],ax
  773.          mov _vys[edi*2],bx
  774.          pop edi esi
  775.  
  776.          ret
  777.  
  778.          align 4
  779.  
  780. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  781. ; _point_dir: Point object SI in direction it is moving
  782. ; In:
  783. ;    SI = object # to point
  784. ;  _xadds[esi*4] = direction object is moving
  785. ;  _yadds[esi*4] =    "           "
  786. ;  _zadds[esi*4] =    "           "
  787. ; Out:
  788. ;   _vxs[esi*2]=AX= x angle (in case you need it)
  789. ;   _vys[esi*2]=BX= y angle
  790. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  791.  
  792. _point_dir:
  793.          movzx esi,si
  794.  
  795.          mov ebx,_xadds[esi*4]
  796.          mov ecx,_yadds[esi*4]
  797.          mov ebp,_zadds[esi*4]
  798.  
  799.          shl ebx,4                          ; * whatever to get some decimal accuracy
  800.          shl ecx,4
  801.          shl ebp,4
  802.  
  803.          mov edi,esi                        ; xchange so user doesn't get confused
  804.          push edi
  805.  
  806.          call _calc_middle
  807.  
  808.          pop esi
  809.          mov _vxs[esi*2],ax
  810.          mov _vys[esi*2],bx
  811.  
  812.          ret
  813.  
  814.          align 4
  815.  
  816. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  817. ; _point_dir_time: Point object SI in direction it is moving in DI frames
  818. ; In:
  819. ;    SI = object # to point
  820. ;    DI = time to arrive at angle
  821. ;  _xadds[esi*4] = direction object is moving
  822. ;  _yadds[esi*4] =    "           "
  823. ;  _zadds[esi*4] =    "           "
  824. ; Out:
  825. ;   _vxadds[esi*2]= x angle counter
  826. ;   _vyadds[esi*2]= y angle counter
  827. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  828.  
  829. _point_dir_time:
  830.          movzx edi,di
  831.          push edi
  832.  
  833.          movzx esi,si
  834.  
  835.          mov ebx,_xadds[esi*4]
  836.          mov ecx,_yadds[esi*4]
  837.          mov ebp,_zadds[esi*4]
  838.  
  839.          shl ebx,4                          ; * whatever to get some decimal accuracy
  840.          shl ecx,4
  841.          shl ebp,4
  842.  
  843.          mov edi,esi                        ; xchange so user doesn't get confused
  844.          push edi
  845.  
  846.          call _calc_middle
  847.  
  848.          pop esi
  849.          pop edi
  850.  
  851.          sub ax,_vxs[esi*2]
  852.  
  853.          cwd
  854.          idiv di
  855.          mov _vxadds[esi*2],ax
  856.  
  857.          sub bx,_vys[esi*2]
  858.  
  859.          mov ax,bx
  860.          cwd
  861.          idiv di
  862.          mov _vyadds[esi*2],ax
  863.  
  864.          mov _acountx[esi*2],di
  865.          mov _acounty[esi*2],di
  866.          ret
  867.  
  868.          align 4
  869.  
  870. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  871. ; _point_to: Point object SI at location EBX,ECX,EBP.
  872. ; In:
  873. ;    SI = object # to point
  874. ;   EBX = x location
  875. ;   ECX = y location
  876. ;   EBP = z location
  877. ; Out:
  878. ;   _vxs[esi*2]=AX= x angle (in case you need it)
  879. ;   _vys[esi*2]=BX= y angle
  880. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  881.  
  882. _point_to:
  883.          mov di,si                          ; xchange so user doesn't get confused
  884.          movzx edi,di
  885.          push edi
  886.  
  887.          sub ebx,_xs[edi*4]                 ; get displacement of esi to edi
  888.          sub ecx,_ys[edi*4]
  889.          sub ebp,_zs[edi*4]
  890.  
  891.          call _calc_middle
  892.  
  893.          pop esi
  894.          mov _vxs[esi*2],ax
  895.          mov _vys[esi*2],bx
  896.  
  897.          ret
  898.  
  899.          align 4
  900.  
  901. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  902. ; _set_speed: "Move object in direction it is pointing"
  903. ;              Set speed of object si to ebp*angle, then set _lcount to di
  904. ;
  905. ; In:
  906. ;    SI = object # to set speed of
  907. ;   EBP = signed speed (10000 is good, 1 is dead slow, 10000000 is light speed, fffff000 = 4096 reverse)
  908. ; Out:
  909. ;    EBX = x velocity
  910. ;    ECX = x velocity
  911. ;    EBP = x velocity
  912. ;     DI = 65535 (for counter if you want it)
  913. ;
  914. ; Notes:
  915. ;    EBX= (- cosx * siny) * ebp
  916. ;    ECX=        (- sinx) * ebp
  917. ;    EBP=   (cosx * cosy) * ebp
  918. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  919.  
  920. _set_speed:
  921.          movzx esi,si
  922.  
  923.          mov ax,_vxs[esi*2]
  924.          neg ax
  925.          push eax
  926.          call _cosine
  927.          mov ecx,eax                        ; cx = cos x
  928.          pop eax
  929.          call _sine
  930.  
  931.          neg eax
  932.          imul ebp                           ; set y speed
  933.          shrd eax,edx,14
  934.          push eax
  935.  
  936.          mov ax,_vys[esi*2]
  937.          neg ax
  938.          push eax
  939.          call _cosine
  940.          mov edx,eax                        ; dx = cos y
  941.          pop eax
  942.          call _sine
  943.  
  944.          mov ebx,edx                        ; save because imul trashes dx
  945.  
  946.          imul ecx                           ; ax = sy * cx
  947.          shrd eax,edx,14                    ; shr eax,14 compensates for cos decimals
  948.          imul ebp
  949.          shrd eax,edx,14
  950.          neg eax
  951.          push eax
  952.  
  953.          mov eax,ebx
  954.          imul ecx
  955.          shrd eax,edx,14
  956.          imul ebp
  957.          shrd eax,edx,14
  958.  
  959.          mov ebp,eax
  960.          pop ebx
  961.          pop ecx
  962.  
  963.          mov edi,65535
  964.  
  965.          ret
  966.  
  967. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  968. ; _set_xyzadds:  Set velocity of object SI in world co-ordinates
  969. ; In:
  970. ;  EBX - x velocity
  971. ;  ECX - y velocity
  972. ;  EBP - z velocity
  973. ;   DI - time for travel (_lcount)
  974. ;
  975. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  976.  
  977. _set_xyzadds:
  978.          movzx esi,si
  979.          mov _xadds[esi*4],ebx
  980.          mov _yadds[esi*4],ecx
  981.          mov _zadds[esi*4],ebp
  982.          mov _lcount[esi*2],di
  983.          ret
  984.  
  985. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  986. ; _set_xyzvadds:  Set angular velocity of object SI in world co-ordinates
  987. ; In:
  988. ;   BX - x angular velocity
  989. ;   CX - y angular velocity
  990. ;   BP - z angular velocity
  991. ;   DI - time for travel (_acountxyz)
  992. ;
  993. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  994.  
  995. _set_xyzvadds:
  996.          movzx esi,si
  997.          mov _vxadds[esi*2],bx
  998.          mov _vyadds[esi*2],cx
  999.          mov _vzadds[esi*2],bp
  1000.          mov _acountx[esi*2],di
  1001.          mov _acounty[esi*2],di
  1002.          mov _acountz[esi*2],di
  1003.          ret
  1004.  
  1005. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1006. ; _point_time: Point object SI at location EBX,ECX,EBP, in DI frames (DI = time)
  1007. ; In:
  1008. ;   EBX = x location
  1009. ;   ECX = y location
  1010. ;   EBP = z location
  1011. ;    SI - # of object to spin/twist/roll...
  1012. ;    DI - # of frames to get there
  1013. ; Out:
  1014. ;    BX - x anglular velocity
  1015. ;    CX - y anglular velocity
  1016. ;    BP - z anglular velocity
  1017. ;    SI - # of object to spin/twist/roll...
  1018. ;    DI - # of frames to get there
  1019. ;
  1020. ; Notes:
  1021. ;  This could also be used for the camera, but if you are  going  to
  1022. ;  point the camera at an object, call _cam_newfollow instead.  _cam_newfollow
  1023. ;  allows for when the object is moving - _cam_newfollow will  track  the
  1024. ;  object as it moves and even  if  it   accelerates!    The  camera
  1025. ;  movement/turning must have high  resolution or  the  viewer  will
  1026. ;  notice a "glitch" or "jump".
  1027. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1028.  
  1029. _point_time:
  1030.          call _time_to_point
  1031.  
  1032. ;        add ebx,000010000h                 ; do this if you want more than one rotation
  1033. ;        add ecx,000020000h                 ; along a selected axis.
  1034. ;        add ebp,0fffc0000h
  1035.  
  1036.          jmp _twist_si                      ; twist object to this location in di frames!
  1037.  
  1038. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1039. ; _time_to_point: Calculate timed angles in preparation for roll.
  1040. ; In:
  1041. ;   EBX = x location
  1042. ;   ECX = y location
  1043. ;   EBP = z location
  1044. ;    SI - # of object to spin/twist/roll...
  1045. ;    DI - # of frames to get there
  1046. ; Out:
  1047. ;   EBX - x angle  (_sine extended for direction of roll)
  1048. ;   ECX - y angle
  1049. ;    SI - # of object to spin/twist/roll...
  1050. ;    DI - # of frames to get there
  1051. ;
  1052. ; Notes:
  1053. ;  Output is ready for _twist_si routine.  But you can add high words  to  the
  1054. ;  output in order to get it to roll more than 1 rotation.  See example above
  1055. ;  The direction for rotation is defined by the closest angle.
  1056. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1057.  
  1058. _time_to_point:
  1059.          push edi esi edi esi ebp ecx ebx
  1060.          call _where_si                     ; find out where object will be in di frames
  1061.  
  1062.          pop eax                            ; get x location to look at
  1063.          sub ebx,eax                        ; get displacement of where it will be to where
  1064.          neg ebx                            ; it should point
  1065.  
  1066.          pop eax                            ; get y location to look at
  1067.          sub ecx,eax
  1068.          neg ecx
  1069.  
  1070.          pop eax                            ; get z location to look at
  1071.          sub ebp,eax
  1072.          neg ebp
  1073.  
  1074.          pop edi esi                        ; notice reverse order for _calc_middle!
  1075.  
  1076.          call _calc_middle
  1077.          pop esi                            ; pop object number
  1078.          pop edi                            ; pop time
  1079.          movzx esi,si
  1080.  
  1081.          push ax bx                         ; save x angle,yangle
  1082.          sub ax,_vxs[esi*2]
  1083.          sub bx,_vys[esi*2]
  1084.          movsx ecx,bx                       ; set _sine for rotations
  1085.          movsx ebx,ax
  1086.  
  1087.          pop cx bx                          ; cx = y angle, bx = x angle
  1088.          ret
  1089.  
  1090.          align 4
  1091.  
  1092. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1093. ; Default/Null cross referencing palette: eg 1=1, 7=7, 221=221...
  1094. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1095. _nullpalette:
  1096.          i=0
  1097.          rept 256
  1098.          db i
  1099.          i=i+1
  1100.          endm
  1101.  
  1102.          align 4
  1103.  
  1104. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1105. ; _set_xref_palette: Set cross referencing palette for object si
  1106. ; In:
  1107. ;  ESI = object #
  1108. ;   BL = selected cross referencing palette number (eg 0,1,2,3,4)
  1109. ;
  1110. ; Notes:
  1111. ;  Each object can have its own colour scheme by setting the cross  reference
  1112. ;  palette to re-direct the actual colours to a new set of colours.  The xref
  1113. ;  palette doesn't have to be 256 bytes long,  it only needs to re-direct the
  1114. ;  colours that your selected object has.
  1115. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1116.  
  1117. _set_xref_palette:
  1118.          movzx esi,si
  1119.          mov _palxref[esi],bl
  1120.          ret
  1121.  
  1122. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1123. ; _fix_xangle: Force x angle of object to remain within range +- 16384
  1124. ;  In: ESI = object to modify
  1125. ;
  1126. ; Notes: This routine can be called once every frame.   The  purpose  of  this
  1127. ; routine is to prevent  an objects x   angle  from  making  the  object  turn
  1128. ; upsidedown.  All the routine will do is, when the x angle goes out-of-range,
  1129. ; this will turn the y angle 180degrees and also turn the x angle  180degrees.
  1130. ; The objects x angular velocity will also be negated.
  1131. ;
  1132. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1133.  
  1134. _fix_xangle:
  1135.          mov ax,_vxs[esi*2]
  1136.          add ax,16384
  1137.          cmp ax,0
  1138.          je fixxzero
  1139.          cmp ax,32768
  1140.          je fixxzero
  1141.          ja fixxangle
  1142.          ret
  1143. fixxangle:
  1144.          add _vys[esi*2],32768
  1145.          add _vzs[esi*2],32768
  1146.          mov ax,16384
  1147.          sub ax,_vxs[esi*2]
  1148.          shl ax,1
  1149.          add _vxs[esi*2],ax
  1150.          neg _vxadds[esi*2]
  1151.          ret
  1152. fixxzero:
  1153.          mov ax,_vzs[esi*2]
  1154.          mov _vzs[esi*2],0
  1155.          mov _vys[esi*2],ax
  1156.          ret
  1157.  
  1158. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1159. ; This fix routine looks great with the joystick, but it is more like a brick
  1160. ; wall than a correct solution to x angle inversion.
  1161. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1162.  
  1163. _fix_xangleq:
  1164.          mov ax,_eyeax
  1165.          add ax,16384
  1166.          cmp ax,32768
  1167.          ja fixxangleq
  1168.          ret
  1169. fixxangleq:
  1170.          cmp _eyeax,0
  1171.          jl fixqqq
  1172.          mov _eyeax,16383
  1173.          ret
  1174. fixqqq:
  1175.          mov _eyeax,-16383
  1176.          ret
  1177.  
  1178. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1179. ; Subtract camera: Make x,y,z relative to camera.
  1180. ; In:
  1181. ;   EBX = x location
  1182. ;   ECX = y location
  1183. ;   EBP = z location
  1184. ; Out:
  1185. ;   EBX = x location
  1186. ;   ECX = y location
  1187. ;   EBP = z location
  1188. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1189.  
  1190. _subtract_camera:
  1191.          sub ebx,_eyex
  1192.          sub ecx,_eyey
  1193.          sub ebp,_eyez
  1194.          ret
  1195.  
  1196. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1197. ; _Relative_velocity: Get difference in velocities between object si and di
  1198. ; In:
  1199. ;  ESI = object #
  1200. ;  EDI = object #
  1201. ; Out:
  1202. ;  EBX - x speed difference
  1203. ;  ECX - y speed difference
  1204. ;  EBP - z speed difference
  1205. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1206. _relative_velocity:
  1207.          movzx edi,di
  1208.          movzx esi,si
  1209.  
  1210.          mov ebx,_xadds[esi*4]
  1211.          mov ecx,_yadds[esi*4]
  1212.          mov ebp,_zadds[esi*4]
  1213.  
  1214.          sub ebx,_xadds[edi*4]
  1215.          sub ecx,_yadds[edi*4]
  1216.          sub ebp,_zadds[edi*4]
  1217.  
  1218.          ret
  1219.  
  1220. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1221. ; Add velocity EBX,ECX,EBP to object ESI
  1222. ; In:
  1223. ;  ESI = object #
  1224. ;  EBX - x speed
  1225. ;  ECX - y speed
  1226. ;  EBP - z speed
  1227. ; Out:
  1228. ;  EBX - x new speed
  1229. ;  ECX - y new speed
  1230. ;  EBP - z new speed
  1231. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1232.  
  1233. _add_xyzadds:
  1234.          add ebx,_xadds[esi*4]
  1235.          add ecx,_yadds[esi*4]
  1236.          add ebp,_zadds[esi*4]
  1237.  
  1238.          ret
  1239.  
  1240. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1241. ; Get velocity of object ESI
  1242. ; In:
  1243. ;  ESI = object #
  1244. ; Out:
  1245. ;  EBX - x speed
  1246. ;  ECX - y speed
  1247. ;  EBP - z speed
  1248. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1249.  
  1250. _get_xyzadds:
  1251.          mov ebx,_xadds[esi*4]
  1252.          mov ecx,_yadds[esi*4]
  1253.          mov ebp,_zadds[esi*4]
  1254.  
  1255.          ret
  1256.  
  1257. code32   ends
  1258.          end
  1259.